home *** CD-ROM | disk | FTP | other *** search
- // REND386 32-BIT INTEGER MATH LIBRARIES
- // All code by Dave Stampe, last updated 23/12/93
-
- // All routines in this library were written by Dave Stampe
- // This code is available to programmers through the REND386
- // project and may be used freely if attribution is given
- // (see COPYRITE.H).
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
-
- /// NOTES ON FORMATS:
- //
- // Several fixed-point formats are used in this library. These
- // are specified by <XX.YY>, where XX is the number of bits to
- // the left and YY is the number of bits to the right of the
- // "decimal point". It's easy to compute how to do math with
- // these (see "Virtual Reality Creations" for more information).
- // The formats are:
- // <32.0>: plain old integer. Used for translational part of matrices
- // <16.16>: value<<16, used for angles (in degrees) and for scaling in general
- // <3.29>: the optimal formats for matrix and trigonometry, with values
- // between +1.0 and -1.0. Used for trig, matrix entries.
- //
- // Many routines expect one or the other of the above fomats: it should
- // be obvious which. Some (such as magnitude) don't really care as long
- // as all the arguments are in the same format.
-
-
- /********* INITIALIZE: DO FIRST!!!!! ********/
-
- extern int init_math(); // returns 0 if OK
-
-
- /************* INTEGER TRIG ************/
- // from intrig.asm
-
- // numbers in <3.29> format, angles in degrees <16.16>
-
- extern long isine(long angle);
- extern long icosine(long angle);
- extern long arcsine(long x);
- extern long arccosine(long x);
- extern long arctan2(long y, long x);
-
-
- /************* MATRIX MATH ************/
- // from matrix.c, matrixm.asm
-
- // HOMOGENOUS MATRIX
- typedef long MATRIX[4][3]; // row major 3x3 rotational matrix
- // plus row [3] is translation
-
- // these are the order in which axes are rotated about
- #define RXYZ 1 /* matrix rotation types */
- #define RYXZ 0 /* ONLY RYXZ has an inverse routine! */
- #define RXZY 2
- #define RZYX 5
- #define RZXY 4
- #define RYZX 6
-
- /* Create rotation/translation "matrix" from angle data. */
- extern void multi_matrix(MATRIX m, long rx, long ry, long rz,
- long tx, long ty, long tz, int type);
-
- extern void std_matrix(MATRIX m, // same, but type = RYXZ only
- long rx, long ry, long rz,
- long tx, long ty, long tz);
-
- /* multiplies upper left 3x3 submatrices A and B giving C */
- /* i.e. ROTATION ONLY */
- extern void matrix_mult(MATRIX a, MATRIX b, MATRIX c);
-
- /* multiplies matrices: A*B->C, including translational part */
- /* i.e. FULL HOMOGENOUS PRODUCT */
- extern void matrix_product(MATRIX a, MATRIX b, MATRIX c);
-
- /* rotate & translate XYZ by matrix */
- extern void matrix_point(MATRIX m, long *xp, long *yp, long *zp);
-
- /* rotate XYZ by matrix */
- extern void matrix_rotate(MATRIX m, long *xp, long *yp, long *zp);
-
- /* generate inverse of rotate matrix (transpose) */
- /* ONLY WORKS FOR ORTHOGONAL MATRICES */
- extern void matrix_transpose(MATRIX a, MATRIX b);
-
- /* generate inverse of rotate/translate matrix */
- extern void inverse_matrix(MATRIX a, MATRIX b);
-
- /* create identity matrix */
- extern void identity_matrix(MATRIX m);
-
- /* copy matrix */
- extern void matrix_copy(MATRIX s, MATRIX d);
-
- /* copies upper left 3x3 submatrix, zeros translation part (bottom row) */
- extern void matrix_rot_copy(MATRIX s, MATRIX d);
-
- /* FAST INTEGER homogenous matrix -> angles (RYXZ only) */
- /* Expects an unscaled rotational matrix */
- extern void matrix_to_angle(MATRIX m, long *rx, long *ry, long *rz);
-
- /* makes matrix that will xform Z axis to given vector */
- extern void vector_to_matrix(MATRIX m, long x, long y, long z);
-
- /* fixes matrix scale, needed to fix shrinkage */
- /* after many matrix products */
- extern void renormalize_matrix(MATRIX m);
-
- /* replaces <col> of matrix with cross product of other two */
- extern void cross_column(MATRIX m, int col);
-
-
-
- /************* MAGNITUDES AND SQUARE ROOTS *************/
-
- // these are really fast: avg. 200 clocks for 32 bit, 400 clocks for 62 bit
-
- /* compute 16-bit root of a 32-bit unsigned argument */
- extern long squareroot32(long x);
-
- /* compute 31-bit root of a 62-bit unsigned argument */
- /* needs top 2 bits clear for overflow */
- extern long squareroot62(long xh, long xl);
-
- /* computes magnitude of 16-bit vector */
- extern long magnitude16(long a, long b, long c);
-
- /* computes magnitude of 32-bit vector */
- extern long magnitude32(long a, long b, long c);
-
- /* scales vector */
- extern void set_vector_magnitude32(long length, long *x, long *y, long *z);
-
-
-
- /************* MISC FIXED-POINT MATH *************/
-
- /* returns (ax+by+cz)>>29) */
- /* DOT PRODUCT: massively useful for splits, visibility, etc. */
- extern long dot_prod_29(long a, long b, long c, long x, long y, long z);
-
- // another massively useful function for scaling, tweening and
- // so on. Performs (a*b)/c with 64-bit intermediate result
- // remainder stored in longmath_overflow
- extern long mulmuldiv(long a, long b, long c);
-
-
- // LONG SUPPORT: these are included since many compilers have
- // rather poor (slow 16-bit) math for longs.
- // Also, these support 64-bit intermediate results
-
- // this variable is updated with remainder on division,
- // and overflow on multiplies
- extern long longmath_overflow;
-
- /* perform divide, can divide 64 bit by 32 bit */
- /* remainder stored in longmath_overflow */
- extern long divide_long(long ahi, long alo, long b);
-
- /* perform multiply on longs */
- /* any overflow stored in longmath_overflow */
- extern long mult_long(long a, long b);
-
- // shifts 32-bit signed number left or right (>0 is left, <0 is right)
- extern long_shift32(long a, int shift);
-
- // shifts 64-bit signed number left or right (>0 is left, <0 is right)
- // msdword of result is returned in longmath_overflow
- extern long_shift64(long ahi, long alo, int shift);
-
-
- // MISC FIXED POINT
-
- /* perform multiplication of anything by a <3.29> matrix element */
- extern long m_mult(long a, long b);
-
- /* perform TWO multiplications of anything by a <3.29> matrix element */
- extern long m2_mult(long a, long b, long c);
-
- /* divide a by b, result in <3.29> format */
- /* up to user to test for overflow or zero */
- extern long divide_29(long a, long b);
-
- /* these are used for scaling pointer return values */
- /* s is a scaling factor in <16.16> format: returns s*(x+a) */
- extern long scale_16(long s, long a, long x);
-
- /* computes <16.16> scaling factor: 2s/(a-b) */
- /* a and b are desired hi, lo range, s is half of current range */
- extern long calc_scale_16(long a, long b, long s);
-
- /* computes point on plane (usually y given x, z) */
- /* returns (ax+cz+d)/-b) from plane equation */
- extern long plane_y(long a, long b, long c, long d, long x, long z);
-
- /* computes "city-block" distance betweeen points */
- /* used because many compilers have poor long sppt */
- extern long big_dist(long x1, long y1, long z1,
- long x2, long y2, long z2);
-
-
- /************* NOT IN LIBRARY *************/
-
- // these are in int3d.asm, and are specific to REND386
-
- #ifdef OBJDEF
- #ifdef REPDEF // so they are declared for REND386 only
-
- //; tests 3D selection point for best object to select */
- //; returns 0x7FFFFFFF if not in obj bounds, else
- //; <conservative closeness: always greater than actual>
- extern long sphere_pretest(VISOBJ *obj, long x, long y, long z);
-
- /* compute, unitize (3.29 format) normal to plane. */
- /* returns -1 if normal is zero, else log2(length) */
- extern int find_normal(long x1, long y1, long z1,
- long x2, long y2, long z2,
- long x3, long y3, long z3,
- long *xn, long *yn, long *zn);
-
-
- // move an object's sphere only: renderer will
- // move rest when drawn
- extern void matmove_osphere(VISOBJ *obj, MATRIX m);
-
- // move the actual visible object
- extern void matmove_rep(REP *rep, MATRIX m);
-
- #endif
- #endif
-
-
- /* End of intmath.h */
-